package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.exception.LogicException;
import cn.wolfcode.luowowo.repository.UserRepository;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.AssertUtil;
import cn.wolfcode.luowowo.util.Consts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.UUID;

@Service
//@Transactional //目前单体MongoDB不支持事务,后续会讲到
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserRepository repository;
    @Autowired
    private IUserInfoRedisService redisService;

    @Override
    public UserInfo get(String id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public boolean checkPhone(String phone) {
        UserInfo userInfo = repository.findByPhone(phone);
        return userInfo != null;
    }

    @Override
    public void sendVerifyCode(String phone, String smsUrl, String smsMsg, String smsAppkey) {
        //生成验证码(截取4个)
        String code = UUID.randomUUID()
                .toString()
                .replaceAll("-", "")
                .substring(0, 4);
        //将验证码发送到手机
        StringBuilder sb = new StringBuilder(100);
        sb.append("您好,您在骡窝窝上的注册验证码是:")
                .append(code)
                .append(",请在")
                .append(Consts.VERIFY_CODE_VAI_TIME)
                .append("分钟之内使用");

        System.out.println(sb.toString());//假装已经发送了

        //真实发送短信:原理:使用java方式发起http请求调用网关暴露接口
        /*String url = "https://way.jd.com/chuangxin/dxjk" +
                "?mobile=" +
                phone +
                "&content=【创信】你的验证码是：" +
                sb.toString() +
                "，5分钟内有效！&appkey=a9d4e36109526bc2dc5ab4b456b916dd";*/
        /*String url = "https://way.jd.com/kaixintong/kaixintong?mobile=" +
                phone +
                "&content=【凯信通】您的验证码是：" +
                sb.toString() +
                "&appkey=a9d4e36109526bc2dc5ab4b456b916dd";*/
        //java中发送http请求
        RestTemplate template = new RestTemplate();
        //String ret = template.getForObject(smsUrl,String.class,phone,sb.toString(),smsAppkey);
        String ret = template.getForObject(smsUrl, String.class, phone, sb.toString(), smsAppkey);
        System.out.println(ret);
        if (!ret.contains("查询成功")) {
            throw new LogicException("短信发送失败");
        }
        //缓存这个验证码:redis 有效时间5分钟
        redisService.setVerifyCode(phone, code);
    }

    @Override
    public UserInfo selectByName(String nickname) {
        return repository.findByNickname(nickname);
    }

    @Override
    public String selectByCode(String phone) {
        return redisService.getCodeNum(phone);
    }

    @Override
    public int getCount() {
        return redisService.getCount();
    }

    @Override
    public void regist(String nickname, String phone, String password, String verifyCode, String rpassword) {
        //1.判断参数是否为空
        AssertUtil.hasLength(phone, "手机号码不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "再次输入的密码不能为空");
        AssertUtil.hasLength(verifyCode, "验证码不能为空");
        //2.判断2次密码是否一致
        AssertUtil.isEqueals(password, rpassword, "2次输入的密码不一样");
        //3.判断手机号码格式是否正确
        String regex = "^1[3-9]\\d{9}$";
        boolean matches = phone.matches(regex);
        if (!phone.matches(regex)) {
            throw new RuntimeException("手机号格式不对");
        }
        //4.判断手机号码是否唯一
        if (this.checkPhone(phone)) {
            throw new RuntimeException("手机号已被注册");
        }
        //5.判断验证码是否一致 redis中的 和传过来的
        String code = redisService.getVerifyCode(phone);
        if (code == null || !code.equalsIgnoreCase(verifyCode)) {
            throw new RuntimeException("验证码已过期或输入错误的验证码");
        }
        //6.注册
        //先给一些无用的参数设置默认值
        UserInfo userInfo = new UserInfo();
        userInfo.setEmail("");
        userInfo.setCity("");
        userInfo.setInfo("");
        userInfo.setLevel(1);
        //再给有用的参数设置值
        userInfo.setState(UserInfo.STATE_NORMAL);
        userInfo.setHeadImgUrl("/images/default.jpg");

        userInfo.setPhone(phone);
        userInfo.setNickname(nickname);
        userInfo.setPassword(password);

        //throw new RuntimeException("这是一个很严重的系统异常..");
        //都设置完成之后就可以保存了
        repository.save(userInfo);
    }

    @Override
    public UserInfo login(String username, String password) {
        //进行判空操作
        AssertUtil.hasLength(username, "手机号码不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        //查询用户对象
        //UserInfo user = repository.findByPhoneAndPassword(username,password);
        UserInfo user = repository.findByPhone(username);
        if (user == null || !password.equals(user.getPassword())) {
            throw new LogicException("账号或密码错误");
        }
        //不能将密码传到页面
        user.setPassword(null);
        return user;
    }

    @Override
    public List<UserInfo> list() {
        return repository.findAll();
    }

    @Override
    public List<UserInfo> getByCity(String city) {
        return repository.findByCity(city);
    }
}















